package com.csun.cmny.provider.service.impl;

import com.csun.cmny.base.dto.LoginAuthDto;
import com.csun.cmny.base.enums.ErrorCodeEnum;
import com.csun.cmny.core.support.BaseService;
import com.csun.cmny.mqtt.entity.MsgBodysenorHome;
import com.csun.cmny.provider.dao.DmcDeviceMapper;
import com.csun.cmny.provider.device.csun.camera.entity.CsunCameraData;
import com.csun.cmny.provider.device.csun.sleep.entity.CsunSleepData;
import com.csun.cmny.provider.exceptions.DmcBizException;
import com.csun.cmny.provider.model.constant.DeviceConstant;
import com.csun.cmny.provider.model.constant.DmcConstant;
import com.csun.cmny.provider.model.constant.LifeConstant;
import com.csun.cmny.provider.model.domain.DmcDevice;
import com.csun.cmny.provider.model.domain.DmcDeviceAlert;
import com.csun.cmny.provider.model.domain.DmcPropertyManagement;
import com.csun.cmny.provider.model.dto.device.DeviceBindDto;
import com.csun.cmny.provider.model.dto.device.DevicePageQuery;
import com.csun.cmny.provider.model.dto.device.DeviceQueryDto;
import com.csun.cmny.provider.model.dto.device.DeviceReqDto;
import com.csun.cmny.provider.model.dto.propertyManagement.DeviceDeriveExcelDto;
import com.csun.cmny.provider.model.dto.propertyManagement.MerchantSaveDeviceDto;
import com.csun.cmny.provider.model.dto.version.DeviceUpdateDto;
import com.csun.cmny.provider.model.enums.device.DeviceStatusEnum;
import com.csun.cmny.provider.model.enums.device.DmcDeviceStatusEnum;
import com.csun.cmny.provider.model.enums.device.DmcDeviceTypeEnum;
import com.csun.cmny.provider.model.vo.*;
import com.csun.cmny.provider.model.vo.csunbody.DmcCsunBodySensorVo;
import com.csun.cmny.provider.model.vo.csunbutton.DmcCsunButtonVo;
import com.csun.cmny.provider.model.vo.csuncamera.CameraVo;
import com.csun.cmny.provider.model.vo.csuncamera.CsunCameraVo;
import com.csun.cmny.provider.model.vo.csuncamera.GroupCameraVo;
import com.csun.cmny.provider.model.vo.csunsleep.DmcCsunSleepVo;
import com.csun.cmny.provider.model.vo.device.DeviceTypeVo;
import com.csun.cmny.provider.model.vo.device.DmcDeviceVo;
import com.csun.cmny.provider.model.vo.humidistat.CsunHumidistatVo;
import com.csun.cmny.provider.model.vo.life.DmcDeviceByRoom;
import com.csun.cmny.provider.model.vo.propertyManagement.PropertyManagementDeviceVo;
import com.csun.cmny.provider.resolver.CmnyMessageSource;
import com.csun.cmny.provider.service.*;
import com.csun.cmny.util.PublicUtil;
import com.csun.cmny.util.RedisKeyUtil;
import com.csun.cmny.util.wrapper.Wrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Auther: chisj chisj@foxmal.com
 * @Date: 2018-12-12 10:31
 * @Description:
 */
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class DmcDeviceServiceImpl extends BaseService<DmcDevice> implements DmcDeviceService {

    @Resource
    private CmnyMessageSource cmnyMessageSource;
    @Resource
    private DmcDeviceMapper dmcDeviceDao;
    @Resource
    private DmcCsunButtonLocationService dmcCsunButtonLocationService;
    @Resource
    private DmcCsunBodySensorLocationService dmcCsunBodySensorLocationService;
    @Resource
    private DmcCsunSleepBindService dmcCsunSleepBindService;
    @Resource
    private DmcSleepCareBindService dmcSleepCareBindService;
    @Resource
    private DmcCsunHumidistatLocationService dmcCsunHumidistatLocationService;
    @Resource
    private DmcCsunCameraLocationService dmcCsunCameraLocationService;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private DmcPropertyManagementService propertyManagementService;
    @Resource
    private UacRpcService uacRpcService;

    /**
     * add dmc device
     *
     * @param dmcDevice    the dmc device
     * @param loginAuthDto the login auth dto
     * @return the int
     */
    @Override
    public Integer addDevice(DmcDevice dmcDevice, LoginAuthDto loginAuthDto) {

        // 判断设备是否已经存在
        DmcDevice dmcDeviceQuery = new DmcDevice();
        dmcDeviceQuery.setDeviceNo(dmcDevice.getDeviceNo());

        dmcDeviceQuery = mapper.selectOne(dmcDeviceQuery);

        if (PublicUtil.isNotEmpty(dmcDeviceQuery)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610001);
        }

        // 添加设备信息
        dmcDevice.setStatus(DmcDeviceStatusEnum.ENABLE.getKey());
        dmcDevice.setUpdateInfo(loginAuthDto);
        dmcDevice.setGroupId(loginAuthDto.getGroupId());
        int result = dmcDeviceDao.insertSelective(dmcDevice);
        if (result < 1) {
            throw new DmcBizException(Wrapper.ERROR_CODE, "操作失败");
        }

        return result;
    }

    /**
     * 根据设备Id查询设备信息
     *
     * @param deviceId 设备Id
     * @return 设备信息
     */
    @Override
    public DeviceReqDto getDeviceById(Long deviceId) {

        return dmcDeviceDao.getDeviceById(deviceId);
    }

    /**
     * query group device list with page
     *
     * @param devicePageQuery the base query
     * @return the page info
     */
    @Override
    public PageInfo queryDeviceListWithPage(DevicePageQuery devicePageQuery) {

        PageHelper.startPage(devicePageQuery.getPageNum(), devicePageQuery.getPageSize());
        List<DmcDeviceVo> dmcDeviceVoList = dmcDeviceDao.queryDeviceListWithPage(devicePageQuery);

        return new PageInfo<>(dmcDeviceVoList);
    }

    /**
     * edit dmc device
     *
     * @param dmcDevice    the dmc device
     * @param loginAuthDto the login auth dto
     * @return the int
     */
    @Override
    public Integer editDevice(DmcDevice dmcDevice, LoginAuthDto loginAuthDto) {

        Long id = dmcDevice.getId();
        Preconditions.checkArgument(id != null, "设备Id不能为空");

        DmcDevice dmcDeviceQuery = new DmcDevice();
        dmcDeviceQuery.setId(id);
        dmcDeviceQuery = mapper.selectByPrimaryKey(dmcDeviceQuery);
        if (PublicUtil.isEmpty(dmcDeviceQuery)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610002, id);
        }

        // 判断设备编码是否已经存在
        if (StringUtils.isNotEmpty(dmcDevice.getDeviceNo())) {
            // 需要校验设备编码是否存在
            DmcDevice dmcDeviceExist = new DmcDevice();
            dmcDeviceExist.setDeviceNo(dmcDevice.getDeviceNo());
            dmcDeviceExist = mapper.selectOne(dmcDeviceExist);
            if (PublicUtil.isNotEmpty(dmcDeviceExist) && !id.equals(dmcDeviceExist.getId())) {
                throw new DmcBizException(ErrorCodeEnum.DMC100610001);
            }
        }

        // 修改设备信息
        dmcDeviceQuery.setUpdateInfo(loginAuthDto);
        dmcDeviceQuery.setDeviceNo(dmcDevice.getDeviceNo());
        dmcDeviceQuery.setDeviceName(dmcDevice.getDeviceName());
        dmcDeviceQuery.setRemark(dmcDevice.getRemark());
        int ret = mapper.updateByPrimaryKey(dmcDeviceQuery);

        return ret;
    }

    /**
     * delete dmc device by id
     *
     * @param id the id
     * @return the int
     */
    @Override
    public Integer deleteDmcDeviceById(Long id) {

        Preconditions.checkArgument(id != null, "设备Id不能为空");

        DmcDevice dmcDeviceQuery = new DmcDevice();
        dmcDeviceQuery.setId(id);
        dmcDeviceQuery = mapper.selectByPrimaryKey(dmcDeviceQuery);
        if (PublicUtil.isEmpty(dmcDeviceQuery)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610002, id);
        }

        Integer result = dmcDeviceDao.deleteByPrimaryKey(id);

        return result;
    }

    /**
     * check device is watch by device id
     *
     * @param deviceId device id
     * @return the dmc device
     */
    @Override
    public DmcDevice checkDeviceIsWatchByDeviceId(Long deviceId) {

        Preconditions.checkArgument(deviceId != null,
                cmnyMessageSource.getMessage("device.id.null", null));

        // 1.判断设备Id是否存在
        DmcDevice dmcDevice = dmcDeviceDao.selectByPrimaryKey(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610002, deviceId);
        }

        // 2.判断设备是否为孝心手环
        if (!dmcDevice.getDeviceType().equals(DmcDeviceTypeEnum.XX_WATCH.getIndex())) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610013, deviceId, dmcDevice.getDeviceType(),
                    DmcDeviceTypeEnum.getKey(dmcDevice.getDeviceType()));
        }

        return dmcDevice;
    }

    /**
     * check device is rfid reader by device id
     *
     * @param deviceId device id
     * @return the dmc device
     */
    @Override
    public DmcDevice checkDeviceIsRfidReaderByDeviceId(Long deviceId) {

        Preconditions.checkArgument(deviceId != null,
                cmnyMessageSource.getMessage("device.id.null", null));

        // 1.判断设备Id是否存在
        DmcDevice dmcDevice = dmcDeviceDao.selectByPrimaryKey(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610002, deviceId);
        }

        // 2.判断设备是否为门禁读卡器
        if (!dmcDevice.getDeviceType().equals(DmcDeviceTypeEnum.RFID_READER.getIndex())) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610015, deviceId, dmcDevice.getDeviceType(),
                    DmcDeviceTypeEnum.getKey(dmcDevice.getDeviceType()));
        }

        return dmcDevice;
    }

    /**
     * check device is rfid label by device id
     *
     * @param deviceId device id
     * @return the dmc device
     */
    @Override
    public DmcDevice checkDeviceIsRfidLabelByDeviceId(Long deviceId) {

        // 1.判断设备Id是否存在
        DmcDevice dmcDevice = dmcDeviceDao.selectByPrimaryKey(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610002, deviceId);
        }

        // 2.判断设备是否为门禁卡标签
        if (!dmcDevice.getDeviceType().equals(DmcDeviceTypeEnum.RFID_LABEL.getIndex())) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610017, deviceId, dmcDevice.getDeviceType(),
                    DmcDeviceTypeEnum.getKey(dmcDevice.getDeviceType()));
        }

        return dmcDevice;
    }

    /**
     * check device is phone by device id
     *
     * @param deviceId device id
     * @return the dmc device
     */
    @Override
    public DmcDevice checkDeviceIsPhoneByDeviceId(Long deviceId) {

        // 1.判断设备Id是否存在
        DmcDevice dmcDevice = dmcDeviceDao.selectByPrimaryKey(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610002, deviceId);
        }

        // 2.判断设备是否为智能电话机
        if (!dmcDevice.getDeviceType().equals(DmcDeviceTypeEnum.ZN_PHONE.getIndex())) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610021, deviceId, dmcDevice.getDeviceType(),
                    DmcDeviceTypeEnum.getKey(dmcDevice.getDeviceType()));
        }

        return dmcDevice;
    }

    /**
     * check device is csun body sensor by device id
     *
     * @param deviceId device id
     *
     * @return the dmc device
     */
    @Override
    public DmcDevice checkDeviceIsCsunBodySensorByDeviceId(Long deviceId) {

        // 1.判断设备Id是否存在
        DmcDevice dmcDevice = dmcDeviceDao.selectByPrimaryKey(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610002, deviceId);
        }

        // 2.判断设备是否为人体感应
        if (!dmcDevice.getDeviceType().equals(DmcDeviceTypeEnum.CSUN_BODY_SENSOR.getIndex())) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610025, deviceId, dmcDevice.getDeviceType(),
                    DmcDeviceTypeEnum.getKey(dmcDevice.getDeviceType()));
        }

        return dmcDevice;
    }

    /**
     * check device is csun new body sensor by device id
     *
     * @param deviceId device id
     *
     * @return the dmc device
     */
    @Override
    public DmcDevice checkDeviceIsCsunNewBodySensorByDeviceId(Long deviceId) {

        // 1.判断设备Id是否存在
        DmcDevice dmcDevice = dmcDeviceDao.selectByPrimaryKey(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610002, deviceId);
        }

        // 2.判断设备是否为人体感应
        if (!dmcDevice.getDeviceType().equals(DmcDeviceTypeEnum.NEWBODY.getIndex())) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610025, deviceId, dmcDevice.getDeviceType(),
                    DmcDeviceTypeEnum.getKey(dmcDevice.getDeviceType()));
        }

        return dmcDevice;
    }

    @Override
    public List<PropertyManagementDeviceVo> selectDeviceByDeviceIds(DeviceDeriveExcelDto deriveExcelDto) {
        return dmcDeviceDao.selectDeviceByDeviceIds(deriveExcelDto);
    }

    @Override
    public int saves(List<DmcDevice> devices) {
        return dmcDeviceDao.saves(devices);
    }

    @Override
    public int deleteManagements(List<Long> deviceIds) {
        propertyManagementService.deleteManagements(deviceIds);
        return dmcDeviceDao.deleteManagements(deviceIds);
    }

    /**
     * select device id list
     *
     * @param devicePageQuery
     * @return
     */
    @Override
    public List<Long> selectDeviceIdList(DevicePageQuery devicePageQuery) {

        return dmcDeviceDao.selectDeviceIdList(devicePageQuery);
    }

    @Override
    public int bindDeviceGroup(ArrayList<String> deviceNos, Long groupId) {

        for (String deviceNo : deviceNos) {
            //物管更新初始化时间
            DmcDevice dmcDevice = new DmcDevice();
            dmcDevice.setDeviceNo(deviceNo);
            DmcDevice device = dmcDeviceDao.selectOne(dmcDevice);

            DmcPropertyManagement dmcPropertyManagement = new DmcPropertyManagement();
            dmcPropertyManagement.setDeviceId(device.getId());
            dmcPropertyManagement.setInitializeDate(new Date());

            propertyManagementService.update(dmcPropertyManagement);
        }

        return dmcDeviceDao.bindDeviceGroup(deviceNos,groupId);
    }

    @Override
    public int bindOnedeviceGroup(MerchantSaveDeviceDto merchantSaveDeviceDto, Long groupId) {


        //更新初始化时间
        DmcDevice dmcDevice = new DmcDevice();
        dmcDevice.setDeviceNo(merchantSaveDeviceDto.getDeviceNo());
        DmcDevice device = dmcDeviceDao.selectOne(dmcDevice);
        DmcPropertyManagement dmcPropertyManagement = new DmcPropertyManagement();
        dmcPropertyManagement.setDeviceId(device.getId());
        dmcPropertyManagement.setInitializeDate(new Date());
        propertyManagementService.update(dmcPropertyManagement);


        return dmcDeviceDao.bindOnedeviceGroup(merchantSaveDeviceDto,groupId);
    }

    @Override
    public int deleteuntie(List<Long> deviceIds) {
        return dmcDeviceDao.deleteuntie(deviceIds);
    }

    /**
     * 查询机构摄像头列表
     *
     * @return
     */
    @Override
    public List<GroupCameraVo> selectGroupCamera() {

        // 查询机构列表
        List<RpcGroupVo> rpcGroupVoList = uacRpcService.queryGroupList();

        // 查询所有的摄像头
        DmcDevice dmcDevice = new DmcDevice();
        dmcDevice.setDeviceType(DmcDeviceTypeEnum.CSUN_CAMERA.getIndex());
        List<DmcDevice> dmcDeviceList = dmcDeviceDao.select(dmcDevice);

        Map<Long, List<CameraVo>> map = Maps.newHashMap();

        Iterator<DmcDevice> iterator = dmcDeviceList.iterator();
        while (iterator.hasNext()) {

            DmcDevice d = iterator.next();

            CameraVo cameraVo = new CameraVo();
            cameraVo.setDeviceNo(d.getDeviceNo());
            cameraVo.setDeviceId(d.getId());

            List<CameraVo> cameraList = map.get(d.getGroupId());
            if (PublicUtil.isEmpty(cameraList)) {
                cameraList = Lists.newArrayList();
            }
            cameraList.add(cameraVo);
            map.put(d.getGroupId(), cameraList);
        }

        List<GroupCameraVo> groupCameraVoList = Lists.newArrayList();
        for (RpcGroupVo rgv : rpcGroupVoList) {
            GroupCameraVo groupCameraVo = new GroupCameraVo();
            groupCameraVo.setGroupId(rgv.getGroupId());
            groupCameraVo.setGroupName(rgv.getGroupName());

            List<CameraVo> cameraList = map.get(rgv.getGroupId());
            if (PublicUtil.isEmpty(cameraList)) {
                cameraList = Lists.newArrayList();
            }
            groupCameraVo.setCameraList(cameraList);
            groupCameraVoList.add(groupCameraVo);
        }

        return groupCameraVoList;
    }


    /**
     * check device is csun button by device id
     *
     * @param deviceId device id
     * @return the dmc device
     */
    @Override
    public DmcDevice checkDeviceIsCsunButtonByDeviceId(Long deviceId) {

        // 1.判断设备Id是否存在
        DmcDevice dmcDevice = dmcDeviceDao.selectByPrimaryKey(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610002, deviceId);
        }

        // 2.判断设备是否为紧急按钮
        if (!dmcDevice.getDeviceType().equals(DmcDeviceTypeEnum.CSUN_BUTTON.getIndex())) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610026, deviceId, dmcDevice.getDeviceType(),
                    DmcDeviceTypeEnum.getKey(dmcDevice.getDeviceType()));
        }

        return dmcDevice;
    }

    /**
     * check device is csun sleep by device id
     *
     * @param deviceId device id
     * @return the dmc device
     */
    @Override
    public DmcDevice checkDeviceIsCsunSleepByDeviceId(Long deviceId) {

        // 1.判断设备Id是否存在
        DmcDevice dmcDevice = dmcDeviceDao.selectByPrimaryKey(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610002, deviceId);
        }

        // 2.判断设备是否为日创床垫
        if (!dmcDevice.getDeviceType().equals(DmcDeviceTypeEnum.CSUN_SLEEP.getIndex())) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610033, deviceId, dmcDevice.getDeviceType(),
                    DmcDeviceTypeEnum.getKey(dmcDevice.getDeviceType()));
        }

        return dmcDevice;
    }

    /**
     * check device is csun camera by device id
     *
     * @param deviceId device id
     * @return the dmc device
     */
    @Override
    public DmcDevice checkDeviceIsCsunCameraByDeviceId(Long deviceId) {

        // 1.判断设备Id是否存在
        DmcDevice dmcDevice = dmcDeviceDao.selectByPrimaryKey(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610002, deviceId);
        }

        // 2.判断设备是否为日创摄像头
        if (!dmcDevice.getDeviceType().equals(DmcDeviceTypeEnum.CSUN_CAMERA.getIndex())) {
            throw new DmcBizException(ErrorCodeEnum.DMC10068003, deviceId, dmcDevice.getDeviceType(),
                    DmcDeviceTypeEnum.getKey(dmcDevice.getDeviceType()));
        }

        return dmcDevice;

    }

    /**
     * check device is sleep care by device id
     *
     * @param deviceId device id
     * @return the dmc device
     */
    @Override
    public DmcDevice checkDeviceIsSleepCareByDeviceId(Long deviceId) {

        // 1.判断设备Id是否存在
        DmcDevice dmcDevice = dmcDeviceDao.selectByPrimaryKey(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610002, deviceId);
        }

        // 2.判断设备是否为日创床垫
        if (!dmcDevice.getDeviceType().equals(DmcDeviceTypeEnum.BS_SLEEP.getIndex())) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610040, deviceId, dmcDevice.getDeviceType(),
                    DmcDeviceTypeEnum.getKey(dmcDevice.getDeviceType()));
        }

        return dmcDevice;
    }

    /**
     * check device is follow by device id
     *
     * @param deviceId device id
     * @return the dmc device
     */
    @Override
    public DmcDevice checkDeviceIsFollowByDeviceId(Long deviceId) {

        // 1.判断设备Id是否存在
        DmcDevice dmcDevice = dmcDeviceDao.selectByPrimaryKey(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610002, deviceId);
        }

        // 2.判断设备是否为随访仪
        if (!dmcDevice.getDeviceType().equals(DmcDeviceTypeEnum.FOLLOW.getIndex())) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610042, deviceId, dmcDevice.getDeviceType(),
                    DmcDeviceTypeEnum.getKey(dmcDevice.getDeviceType()));
        }

        return dmcDevice;
    }

    @Override
    public DmcDevice checkDeviceIsRadarByDeviceId(Long deviceId) {
        // 1.判断设备Id是否存在
        DmcDevice dmcDevice = dmcDeviceDao.selectByPrimaryKey(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610002, deviceId);
        }
        // 2.判断设备是否为随访仪
        if (!dmcDevice.getDeviceType().equals(DmcDeviceTypeEnum.FALL_RADAR.getIndex())) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610042, deviceId, dmcDevice.getDeviceType(),
                    DmcDeviceTypeEnum.getKey(dmcDevice.getDeviceType()));
        }

        return dmcDevice;
    }

    /**
     * check device is csun gateway by device id
     *
     * @param deviceId the device id
     * @return the dmc device
     */
    @Override
    public DmcDevice checkDeviceIsCsunGatewayByDeviceId(Long deviceId) {

        // 1.判断设备Id是否存在
        DmcDevice dmcDevice = dmcDeviceDao.selectByPrimaryKey(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610002, deviceId);
        }

        // 2.判断设备是否为网关
        if (!dmcDevice.getDeviceType().equals(DmcDeviceTypeEnum.CSUN_GATEWAY.getIndex())) {
            throw new DmcBizException(ErrorCodeEnum.DMC100614004, deviceId, dmcDevice.getDeviceType(),
                    DmcDeviceTypeEnum.getKey(dmcDevice.getDeviceType()));
        }

        return dmcDevice;
    }

    /**
     * query gateway list
     *
     * @return
     */
    @Override
    public List<DmcDeviceVo> queryGatewayList() {

        DevicePageQuery devicePageQuery = new DevicePageQuery();
        devicePageQuery.setDeviceType(DmcDeviceTypeEnum.CSUN_GATEWAY.getIndex());

        return dmcDeviceDao.queryDeviceListWithPage(devicePageQuery);
    }

    /**
     * @throws
     * @description: TODO 查询所有设备的数量
     * @param:
     * @return: 设备总数
     * @author huangxm
     * @date 2019/3/8 14:32
     */
    @Override
    public Integer getDeviceSum(Long groupId, Integer deviceType) {
        return dmcDeviceDao.getDeviceSum(groupId, deviceType);
    }

    /**
     * get device bind dto
     *
     * @param dmcDeviceAlert dmc device alert
     * @return the device bind dto
     */
    @Override
    public DeviceBindDto getDeviceBindDto(DmcDeviceAlert dmcDeviceAlert) {

        return getDeviceBindDtoByDeviceId(dmcDeviceAlert.getDeviceId());
    }

    @Override
    public DeviceBindDto getDeviceBindDtoByDeviceId(Long deviceId) {

        DmcDevice dmcDevice = dmcDeviceDao.selectByPrimaryKey(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            return null;
        }

        DeviceBindDto deviceBindDto = new DeviceBindDto();
        switch (dmcDevice.getDeviceType()) {
            case DmcConstant.DEVICE_TYPE_CSUN_BUTTON:
                DmcCsunButtonVo dmcCsunButtonVo = dmcCsunButtonLocationService.getCsunButtonByDeviceId(deviceId);
                if (PublicUtil.isEmpty(dmcCsunButtonVo)) {
                    return null;
                }
                if (PublicUtil.isEmpty(dmcCsunButtonVo.getBindType())) {
                    return null;
                }
                BeanUtils.copyProperties(dmcCsunButtonVo, deviceBindDto);
                break;
            case DmcConstant.DEVICE_TYPE_CSUN_BODY_SENSOR:
                DmcCsunBodySensorVo dmcCsunBodySensorVo = dmcCsunBodySensorLocationService.getCsunBodySensorByDeviceId(deviceId);
                if (PublicUtil.isEmpty(dmcCsunBodySensorVo)) {
                    return null;
                }
                if (PublicUtil.isEmpty(dmcCsunBodySensorVo.getBindType())) {
                    return null;
                }
                BeanUtils.copyProperties(dmcCsunBodySensorVo, deviceBindDto);
                break;
            case DmcConstant.DEVICE_TYPE_CSUN_SLEEP:
                DmcCsunSleepVo dmcCsunSleepVo = dmcCsunSleepBindService.getCsunSleepBindByDeviceId(deviceId);
                if (PublicUtil.isEmpty(dmcCsunSleepVo)) {
                    return null;
                }
                if (PublicUtil.isEmpty(dmcCsunSleepVo.getBindType())) {
                    return null;
                }
                BeanUtils.copyProperties(dmcCsunSleepVo, deviceBindDto);
                break;
            case DmcConstant.DEVICE_TYPE_BS_SLEEP:
                DmcSleepCareVo dmcSleepCareVo = dmcSleepCareBindService.getSleepCareBindByDeviceId(deviceId);
                if (PublicUtil.isEmpty(dmcSleepCareVo)) {
                    return null;
                }
                BeanUtils.copyProperties(dmcSleepCareVo, deviceBindDto);
                break;
            case DmcConstant.DEVICE_TYPE_ALARM_LIGHT:
                deviceBindDto = null;
                break;
            case DmcConstant.DEVICE_TYPE_CSUN_CAMERA:
                CsunCameraVo csunCameraVo = dmcCsunCameraLocationService.getCsunCameraByDeviceNo(dmcDevice.getDeviceNo());
                if (PublicUtil.isEmpty(csunCameraVo)) {
                    return null;
                }
                BeanUtils.copyProperties(csunCameraVo, deviceBindDto);
                break;
            case DmcConstant.DEVICE_TYPE_CSUN_HUMIDISTAT:
                CsunHumidistatVo csunHumidistatVo = dmcCsunHumidistatLocationService.getCsunHumidistatByDeviceNo(dmcDevice.getDeviceNo());
                if (PublicUtil.isEmpty(csunHumidistatVo)) {
                    return null;
                }
                BeanUtils.copyProperties(csunHumidistatVo, deviceBindDto);
                break;
            case DmcConstant.DEVICE_TYPE_CSUN_NEW_BODY :
                DmcCsunBodySensorVo newBodySensor = dmcCsunBodySensorLocationService.getCsunBodySensorByDeviceId(deviceId);
                if (PublicUtil.isEmpty(newBodySensor)) {
                    return null;
                }
                if (PublicUtil.isEmpty(newBodySensor.getBindType())) {
                    return null;
                }
                BeanUtils.copyProperties(newBodySensor, deviceBindDto);
                break;
        }

        return deviceBindDto;
    }

    @Override
    public List<DeviceCountVo> queryDeviceNumByGroupByDeviceType(Long groupId) {
        return dmcDeviceDao.queryDeviceNumByGroupByDeviceType(groupId);
    }

    /**
     * 通过设备编号查询通过设备编号查询设备
     *
     * @param deviceNo
     * @return
     */
    @Override
    public DmcDevice queryDeviceByNumber(String deviceNo) {
        return dmcDeviceDao.queryDeviceByNumber(deviceNo);
    }

    /**
     * 根据设备类型查询绑定的设备
     *
     * @param userId     用户ID
     * @param deviceType 设备类型
     * @return
     */
    @Override
    public List<DmcDevice> queryDeviceBindList(Long userId, Integer deviceType) {
        return dmcDeviceDao.queryDeviceBindList(userId, deviceType);
    }

    @Override
    public List<DmcDeviceVo> queryDeviceListByIdList(List<Long> deviceIdList) {
        return dmcDeviceDao.queryDeviceListByIdList(deviceIdList);
    }


    @Override
    public DmcDevice checkDeviceIsBedsideCareByDeviceId(Long deviceId) {


        // 1.判断设备Id是否存在
        DmcDevice dmcDevice = dmcDeviceDao.selectByPrimaryKey(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610002, deviceId);
        }

        // 2.判断设备是否为床头屏
        if (!dmcDevice.getDeviceType().equals(DmcDeviceTypeEnum.BEDSIDE_SCREEN.getIndex())) {
            throw new DmcBizException(ErrorCodeEnum.DMC10068010, deviceId, dmcDevice.getDeviceType(),
                    DmcDeviceTypeEnum.getKey(dmcDevice.getDeviceType()));
        }

        return dmcDevice;
    }

    @Override
    public DmcDevice checkDeviceIsCsunbedsideBindByDeviceId(Long id) {
        return null;
    }

    @Override
    public PageInfo queryBedsideListWithPage(DevicePageQuery devicePageQuery) {
        PageHelper.startPage(devicePageQuery.getPageNum(), devicePageQuery.getPageSize());
        List<DmcBedsideScreenVo> dmcDeviceVoList = dmcDeviceDao.queryBedsideListWithPage(devicePageQuery);

        for (DmcBedsideScreenVo dmcBedsideScreenVo : dmcDeviceVoList) {
            if (PublicUtil.isNotEmpty(dmcBedsideScreenVo.getBedId())) {
                dmcBedsideScreenVo.setBind(true);
            }
        }

        return new PageInfo<>(dmcDeviceVoList);
    }

    @Override
    public PageInfo queryCMBedsideListWithPage(DevicePageQuery devicePageQuery) {
        PageHelper.startPage(devicePageQuery.getPageNum(), devicePageQuery.getPageSize());
        List<DmcCMBedsideScreenVo> dmcCMBedsideScreenVos = dmcDeviceDao.queryCMBedsideListWithPage(devicePageQuery);

        for(DmcCMBedsideScreenVo dmcCMBedsideScreenVo:dmcCMBedsideScreenVos){
            if(PublicUtil.isNotEmpty(dmcCMBedsideScreenVo.getRoomName())){
                dmcCMBedsideScreenVo.setBind(true);
            }
        }

        return new PageInfo<>(dmcCMBedsideScreenVos);
    }

    /**
     * @param roomId  房间id
     * @param groupId
     * @return
     */
    @Override
    public List<DmcDeviceByRoom> selectDeviceByRoomId(Long roomId, Long groupId) {
        return dmcDeviceDao.selectDeviceByRoomId(roomId, groupId);
    }

    /**
     * @param deviceIds
     * @return
     */
    @Override
    public List<DmcDeviceByRoom> selectRoomIdByDevice(List<Long> deviceIds) {
        return dmcDeviceDao.selectRoomIdByDevice(deviceIds);
    }

    @Override
    public IsInRoomVO getIsInRoomStatus(Long roomId) {
        IsInRoomVO vo = new IsInRoomVO();

        //查询房间绑定的设备类型
        Long groupId = null;
        List<DmcDeviceByRoom> dmcDevices = selectDeviceByRoomId(roomId, groupId);
        if (dmcDevices.size() < 3) {
            return vo;
        }
        /*
         * 2020-03-17 xcr
         * 人感设备处理
         * 一个房间绑定两个人感，编号为双数的人感决定在房状态
         * */
//        Map<String, DmcDeviceByRoom> bodySensorMap = new HashMap<>();
//        dmcDevices.forEach(d -> {
//            if (d.getDeviceType() == DeviceConstant.CSUN_BODY_SENSOR) {
//                bodySensorMap.put(d.getDeviceNo(), d);
//            }
//        });
//        String bodysensorDeviceNo = "";
//        if (bodySensorMap.size() > 1) {
//            Set<String> bodysensorDeviceNoSet = bodySensorMap.keySet();
//            //双数人感上传是否在厕所消息
//            for (String b : bodysensorDeviceNoSet) {
//                String temp = b.substring(b.length() - 1);
//                if (Integer.parseInt(temp) % 2 == 0) {
//                    bodysensorDeviceNo = b;
//                }
//            }
//        }

        //将设备类型保存为map
        Map<Long, String> deviceMap = new HashMap<>();
        dmcDevices.forEach(d -> {
            deviceMap.put(d.getDeviceType(), d.getDeviceNo());
        });
        //将编号为双数的人感重新存储，刷新原来的value
//        if (!bodysensorDeviceNo.equals("")) {
//            deviceMap.put(DmcDeviceTypeEnum.CSUN_BODY_SENSOR.getIndex().longValue(), bodysensorDeviceNo);
//        }
        Set<Long> deviceTypeSet = deviceMap.keySet();

        //定义检测屋中是否有人的设备类型集合
        Set<Long> checkInRoomdeviceMap = Sets.newHashSet(DmcDeviceTypeEnum.NEWBODY.getIndex().longValue(),
                DmcDeviceTypeEnum.CSUN_SLEEP.getIndex().longValue(),
                DmcDeviceTypeEnum.CSUN_CAMERA.getIndex().longValue()
        );

        //如果包含全部设备 检测各个设备的在房情况
        if (deviceTypeSet.containsAll(checkInRoomdeviceMap)) {
            vo.setIsDeviceEnough(LifeConstant.IN_ROOM_STATUS_DEVICE_ENOUGH);
            int flag = 0;
            for (Long type : deviceTypeSet) {
                switch (type.intValue()) {
                    case DeviceConstant.CSUN_CAMERA:
                        CsunCameraData csunCameraData = (CsunCameraData) redisTemplate.opsForValue().get(RedisKeyUtil.getCsunCameraKey(deviceMap.get(DmcDeviceTypeEnum.CSUN_CAMERA.getIndex().longValue())));
                        if (csunCameraData == null || csunCameraData.getStatus().equals(DeviceStatusEnum.OFFLINE.getKey())) {
                            vo.setIsInRoom(LifeConstant.UNKONW_ROOM_STATUS);
                            return vo;
                        }
                        if (csunCameraData.getHomeMsg().equals(LifeConstant.OUT_ROOM_STATUS)) {
                            flag++;
                        } else {
                            vo.setIsInRoom(LifeConstant.IN_ROOM_STATUS);
//                            return vo;
                        }
                        break;
                    case DeviceConstant.CSUN_SLEEP:
                        CsunSleepData csunSleepData = (CsunSleepData) redisTemplate.opsForValue().get(RedisKeyUtil.getCsunSleepKey(deviceMap.get(DmcDeviceTypeEnum.CSUN_SLEEP.getIndex().longValue())));
                        if (csunSleepData == null || csunSleepData.getStatus().equals(DeviceStatusEnum.OFFLINE.getKey())) {
                            vo.setIsInRoom(LifeConstant.UNKONW_ROOM_STATUS);
                            return vo;
                        }
                        if (csunSleepData.getInBed() == 0) {
                            flag++;
                        } else {
                            vo.setIsInRoom(LifeConstant.IN_ROOM_STATUS);
                        }
                        break;
                    case DeviceConstant.NEWBODY:
//                        for(String k : bodySensorMap.keySet()){
//                            if(!redisTemplate.hasKey(RedisKeyUtil.getCsunBodySensorOnline(k))){
//                                log.info(" ==========================> bodysensor offline . >>>RoomId<<< => [{}]", roomId);
//                                vo.setIsInRoom(LifeConstant.UNKONW_ROOM_STATUS);
//                                return vo;
//                            }
//                        }
                        if(!redisTemplate.hasKey(RedisKeyUtil.getCsunBodySensorOnline(deviceMap.get(DmcDeviceTypeEnum.NEWBODY.getIndex().longValue())))){
                            log.info(" ==========================> bodysensor offline . >>>RoomId<<< => [{}]", roomId);
                            vo.setIsInRoom(LifeConstant.UNKONW_ROOM_STATUS);
                            return vo;
                        }
                        //查询人感数据
                        MsgBodysenorHome msgBodysenorHome = (MsgBodysenorHome) redisTemplate.opsForValue().get(RedisKeyUtil.getCsunBodySensorIsInRoomKey(deviceMap.get(DmcDeviceTypeEnum.NEWBODY.getIndex().longValue())));
                        if (msgBodysenorHome == null || msgBodysenorHome.getHomeMsg().equals(LifeConstant.OUT_ROOM_STATUS)) {
                            flag++;
                        } else {
                            vo.setIsInRoom(LifeConstant.IN_ROOM_STATUS);
//                            return vo;
                        }
                        break;
                }
            }
            if (flag == 3) {
                vo.setIsInRoom(LifeConstant.OUT_ROOM_STATUS);
            }
        }
        return vo;
    }

    /**
     * query update device list
     *
     * @param deviceUpdateDto   the device update dto
     *
     * @return the list
     */
    @Override
    public List<DmcDevice> queryUpdateDeviceList(DeviceUpdateDto deviceUpdateDto) {

        if (PublicUtil.isEmpty(deviceUpdateDto.getDeviceIdList())) {
            return null;
        }

        return dmcDeviceDao.queryUpdateDeviceList(deviceUpdateDto);
    }

    /**
     * 更新设备版本号
     *
     * @param deviceId      the device id
     * @param deviceVersion the device version
     *
     * @return the int
     */
    @Override
    public Integer updateDeviceVersion(Long deviceId, String deviceVersion) {

        return dmcDeviceDao.updateDeviceVersion(deviceId, deviceVersion);
    }


    /**
     * 更新设备版本号
     *
     * @param deviceNo  the device no
     * @param version   the version
     *
     * @return  the int.
     */
    @Override
    public Integer updateDeviceVersionByDeviceNo(String deviceNo, String version) {

        return dmcDeviceDao.updateDeviceVersionByDeviceNo(deviceNo, version);
    }

    /**
     * 查询设备列表
     *
     * @param deviceQueryDto the device query dto
     *
     * @return the list
     */
    @Override
    public List<DmcDevice> queryDeviceList(DeviceQueryDto deviceQueryDto) {

        return dmcDeviceDao.queryDeviceList(deviceQueryDto);
    }

    /**
     * 根据设备编号查询设备信息
     *
     * @param deviceNoList the device no list
     * @return the list.
     */
    @Override
    public List<DeviceTypeVo> queryDeviceByDeviceNoList(List<String> deviceNoList) {

        return dmcDeviceDao.queryDeviceByDeviceNoList(deviceNoList);
    }


}
